#include "can.h"


// 静态全局句柄指针（用于中断处理）
static can_handle_t *can1_handle = NULL;
static can_handle_t *can2_handle = NULL;

// CAN初始化
can_driver_status_t can_driver_init(can_handle_t *handle) {
    if (handle == NULL) {
        return CAN_DRIVER_INVALID_PARAM;
    }
    
    if (handle->initialized) {
        return CAN_DRIVER_OK;
    }
    
    CAN_TypeDef *can_instance = handle->config.CANx;
    
    // 使能时钟
    if (can_instance == CAN1) {
        __HAL_RCC_CAN1_CLK_ENABLE();
        can1_handle = handle;
    } else if (can_instance == CAN2) {
        __HAL_RCC_CAN2_CLK_ENABLE();
        __HAL_RCC_CAN1_CLK_ENABLE(); // CAN2需要CAN1时钟
        can2_handle = handle;
    } else {
        return CAN_DRIVER_INVALID_PARAM;
    }
    
    // 配置GPIO
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    // TX引脚配置
    GPIO_InitStruct.Pin = handle->config.tx_gpio_pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = handle->config.tx_gpio_af;
    HAL_GPIO_Init(handle->config.tx_gpio_port, &GPIO_InitStruct);
    
    // RX引脚配置
    GPIO_InitStruct.Pin = handle->config.rx_gpio_pin;
    GPIO_InitStruct.Alternate = handle->config.rx_gpio_af;
    HAL_GPIO_Init(handle->config.rx_gpio_port, &GPIO_InitStruct);
    
    // 配置CAN
    handle->hcan.Instance = can_instance;
    handle->hcan.Init.Prescaler = 0;
    handle->hcan.Init.Mode = CAN_MODE_NORMAL;
    handle->hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
    handle->hcan.Init.TimeSeg1 = CAN_BS1_4TQ;
    handle->hcan.Init.TimeSeg2 = CAN_BS2_3TQ;
    handle->hcan.Init.TimeTriggeredMode = DISABLE;
    handle->hcan.Init.AutoBusOff = DISABLE;
    handle->hcan.Init.AutoWakeUp = DISABLE;
    handle->hcan.Init.AutoRetransmission = DISABLE;
    handle->hcan.Init.ReceiveFifoLocked = DISABLE;
    handle->hcan.Init.TransmitFifoPriority = DISABLE;
    
    // 设置波特率
    if (can_driver_set_baudrate(handle, handle->config.baudrate) != CAN_DRIVER_OK) {
        return CAN_DRIVER_ERROR;
    }
    
    if (HAL_CAN_Init(&handle->hcan) != HAL_OK) {
        return CAN_DRIVER_ERROR;
    }
    
    // 配置过滤器
    for (uint32_t i = 0; i < handle->config.filter_count; i++) {
        if (can_driver_set_filter(handle, &handle->config.filters[i], i) != CAN_DRIVER_OK) {
            return CAN_DRIVER_ERROR;
        }
    }
    
    // 创建发送信号量
    handle->tx_semaphore = xSemaphoreCreateBinary();
    if (handle->tx_semaphore == NULL) {
        return CAN_DRIVER_ERROR;
    }
    xSemaphoreGive(handle->tx_semaphore);
    
    // 创建接收队列
    handle->rx_queue = xQueueCreate(handle->config.rx_buffer_size, sizeof(can_message_t));
    if (handle->rx_queue == NULL) {
        vSemaphoreDelete(handle->tx_semaphore);
        return CAN_DRIVER_ERROR;
    }
    
    // 启动CAN
    if (HAL_CAN_Start(&handle->hcan) != HAL_OK) {
        vSemaphoreDelete(handle->tx_semaphore);
        vQueueDelete(handle->rx_queue);
        return CAN_DRIVER_ERROR;
    }
    
    // 使能中断
    if (HAL_CAN_ActivateNotification(&handle->hcan, CAN_IT_RX_FIFO0_MSG_PENDING | 
                                                   CAN_IT_RX_FIFO1_MSG_PENDING |
                                                   CAN_IT_TX_MAILBOX_EMPTY |
                                                   CAN_IT_ERROR |
                                                   CAN_IT_BUSOFF |
                                                   CAN_IT_LAST_ERROR_CODE) != HAL_OK) {
        vSemaphoreDelete(handle->tx_semaphore);
        vQueueDelete(handle->rx_queue);
        return CAN_DRIVER_ERROR;
    }
    
    // 设置NVIC优先级
    if (can_instance == CAN1) {
        HAL_NVIC_SetPriority(CAN1_TX_IRQn, 5, 0);
        HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 5, 0);
        HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 5, 0);
        HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 5, 0);
        HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
        HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
        HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
        HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
    } else if (can_instance == CAN2) {
        HAL_NVIC_SetPriority(CAN2_TX_IRQn, 5, 0);
        HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 5, 0);
        HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 5, 0);
        HAL_NVIC_SetPriority(CAN2_SCE_IRQn, 5, 0);
        HAL_NVIC_EnableIRQ(CAN2_TX_IRQn);
        HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
        HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
        HAL_NVIC_EnableIRQ(CAN2_SCE_IRQn);
    }
    
    handle->initialized = true;
    return CAN_DRIVER_OK;
}

// 设置波特率
can_driver_status_t can_driver_set_baudrate(can_handle_t *handle, uint32_t baudrate) {
    if (!handle->initialized && handle->hcan.Instance == NULL) {
        return CAN_DRIVER_ERROR;
    }
    
    // 计算预分频器 (APB1时钟为42MHz)
    uint32_t prescaler = 42000000 / (baudrate * (1 + handle->hcan.Init.TimeSeg1 + handle->hcan.Init.TimeSeg2));
    
    if (prescaler == 0 || prescaler > 1024) {
        return CAN_DRIVER_INVALID_PARAM;
    }
    
    handle->hcan.Init.Prescaler = prescaler;
    
    if (handle->initialized) {
        // 重新初始化CAN
        if (HAL_CAN_Init(&handle->hcan) != HAL_OK) {
            return CAN_DRIVER_ERROR;
        }
        return HAL_CAN_Start(&handle->hcan) == HAL_OK ? CAN_DRIVER_OK : CAN_DRIVER_ERROR;
    }
    
    return CAN_DRIVER_OK;
}

// 设置过滤器
can_driver_status_t can_driver_set_filter(can_handle_t *handle, const can_filter_config_t *filter, uint32_t filter_index) {
    if (!handle->initialized) {
        return CAN_DRIVER_ERROR;
    }
    
    CAN_FilterTypeDef can_filter;
    
    can_filter.FilterIdHigh = filter->filter_id_high;
    can_filter.FilterIdLow = filter->filter_id_low;
    can_filter.FilterMaskIdHigh = filter->filter_mask_id_high;
    can_filter.FilterMaskIdLow = filter->filter_mask_id_low;
    can_filter.FilterFIFOAssignment = filter->filter_fifo;
    can_filter.FilterBank = filter->filter_bank;
    can_filter.FilterMode = filter->filter_mode;
    can_filter.FilterScale = filter->filter_scale;
    can_filter.FilterActivation = filter->filter_activation;
    can_filter.SlaveStartFilterBank = 14; // CAN1使用0-13，CAN2使用14-27
    
    if (HAL_CAN_ConfigFilter(&handle->hcan, &can_filter) != HAL_OK) {
        return CAN_DRIVER_ERROR;
    }
    
    return CAN_DRIVER_OK;
}

// 发送消息
can_driver_status_t can_driver_send(can_handle_t *handle, const can_message_t *message, uint32_t timeout) {
    if (!handle->initialized || message == NULL || message->len > 8) {
        return CAN_DRIVER_INVALID_PARAM;
    }
    
    if (xSemaphoreTake(handle->tx_semaphore, pdMS_TO_TICKS(timeout)) != pdTRUE) {
        return CAN_DRIVER_TIMEOUT;
    }
    
    CAN_TxHeaderTypeDef tx_header;
    uint32_t mailbox;
    
    tx_header.StdId = message->format == 0 ? message->id : 0;
    tx_header.ExtId = message->format == 1 ? message->id : 0;
    tx_header.IDE = message->format;
    tx_header.RTR = message->type;
    tx_header.DLC = message->len;
    tx_header.TransmitGlobalTime = DISABLE;
    
    if (HAL_CAN_AddTxMessage(&handle->hcan, &tx_header, (uint8_t*)message->data, &mailbox) != HAL_OK) {
        xSemaphoreGive(handle->tx_semaphore);
        return CAN_DRIVER_ERROR;
    }
    
    return CAN_DRIVER_OK;
}

// 接收消息
can_driver_status_t can_driver_receive(can_handle_t *handle, can_message_t *message, uint32_t timeout) {
    if (!handle->initialized || message == NULL) {
        return CAN_DRIVER_INVALID_PARAM;
    }
    
    if (xQueueReceive(handle->rx_queue, message, pdMS_TO_TICKS(timeout)) != pdTRUE) {
        return CAN_DRIVER_NO_MESSAGE;
    }
    
    return CAN_DRIVER_OK;
}

// 获取接收队列中的消息数量
uint32_t can_driver_get_rx_count(can_handle_t *handle) {
    if (!handle->initialized) {
        return 0;
    }
    
    return uxQueueMessagesWaiting(handle->rx_queue);
}

// CAN反初始化
can_driver_status_t can_driver_deinit(can_handle_t *handle) {
    if (!handle->initialized) {
        return CAN_DRIVER_OK;
    }
    
    HAL_CAN_Stop(&handle->hcan);
    HAL_CAN_DeInit(&handle->hcan);
    
    vSemaphoreDelete(handle->tx_semaphore);
    vQueueDelete(handle->rx_queue);
    
    handle->initialized = false;
    return CAN_DRIVER_OK;
}

// 获取默认配置
void can_driver_get_default_config(can_config_t *config, CAN_TypeDef *can_instance) {
    config->CANx = can_instance;
    config->baudrate = CAN_BAUDRATE_500K;
    
    if (can_instance == CAN1) {
        config->tx_gpio_port = GPIOA;
        config->tx_gpio_pin = GPIO_PIN_11;
        config->tx_gpio_af = GPIO_AF9_CAN1;
        config->rx_gpio_port = GPIOA;
        config->rx_gpio_pin = GPIO_PIN_12;
        config->rx_gpio_af = GPIO_AF9_CAN1;
    } else if (can_instance == CAN2) {
        config->tx_gpio_port = GPIOB;
        config->tx_gpio_pin = GPIO_PIN_13;
        config->tx_gpio_af = GPIO_AF9_CAN2;
        config->rx_gpio_port = GPIOB;
        config->rx_gpio_pin = GPIO_PIN_12;
        config->rx_gpio_af = GPIO_AF9_CAN2;
    }
    
    config->notify_task = NULL;
    config->notify_mask = 0x01;
    config->filters = NULL;
    config->filter_count = 0;
    config->rx_buffer_size = 32;
}

// 获取默认过滤器配置
void can_driver_get_default_filter(can_filter_config_t *filter) {
    filter->filter_id_high = 0x0000;
    filter->filter_id_low = 0x0000;
    filter->filter_mask_id_high = 0x0000;
    filter->filter_mask_id_low = 0x0000;
    filter->filter_fifo = CAN_RX_FIFO0;
    filter->filter_bank = 0;
    filter->filter_mode = CAN_FILTERMODE_IDMASK;
    filter->filter_scale = CAN_FILTERSCALE_32BIT;
    filter->filter_activation = ENABLE;
}

// CAN接收FIFO0中断回调
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
    can_handle_t *handle = NULL;
    
    if (hcan->Instance == CAN1 && can1_handle != NULL) {
        handle = can1_handle;
    } else if (hcan->Instance == CAN2 && can2_handle != NULL) {
        handle = can2_handle;
    }
    
    if (handle != NULL) {
        CAN_RxHeaderTypeDef rx_header;
        can_message_t message;
        
        if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, message.data) == HAL_OK) {
            message.id = rx_header.IDE == CAN_ID_STD ? rx_header.StdId : rx_header.ExtId;
            message.format = rx_header.IDE;
            message.type = rx_header.RTR;
            message.len = rx_header.DLC;
            
            // 发送到接收队列
            xQueueSendFromISR(handle->rx_queue, &message, NULL);
            
            // 通知上层任务
            if (handle->config.notify_task != NULL) {
                BaseType_t xHigherPriorityTaskWoken = pdFALSE;
                xTaskNotifyFromISR(handle->config.notify_task, handle->config.notify_mask, 
                                  eSetBits, &xHigherPriorityTaskWoken);
                portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
            }
        }
    }
}

// CAN接收FIFO1中断回调
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) {
    can_handle_t *handle = NULL;
    
    if (hcan->Instance == CAN1 && can1_handle != NULL) {
        handle = can1_handle;
    } else if (hcan->Instance == CAN2 && can2_handle != NULL) {
        handle = can2_handle;
    }
    
    if (handle != NULL) {
        CAN_RxHeaderTypeDef rx_header;
        can_message_t message;
        
        if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &rx_header, message.data) == HAL_OK) {
            message.id = rx_header.IDE == CAN_ID_STD ? rx_header.StdId : rx_header.ExtId;
            message.format = rx_header.IDE;
            message.type = rx_header.RTR;
            message.len = rx_header.DLC;
            
            // 发送到接收队列
            xQueueSendFromISR(handle->rx_queue, &message, NULL);
            
            // 通知上层任务
            if (handle->config.notify_task != NULL) {
                BaseType_t xHigherPriorityTaskWoken = pdFALSE;
                xTaskNotifyFromISR(handle->config.notify_task, handle->config.notify_mask, 
                                  eSetBits, &xHigherPriorityTaskWoken);
                portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
            }
        }
    }
}

// CAN发送完成回调
void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) {
    can_handle_t *handle = NULL;
    
    if (hcan->Instance == CAN1 && can1_handle != NULL) {
        handle = can1_handle;
    } else if (hcan->Instance == CAN2 && can2_handle != NULL) {
        handle = can2_handle;
    }
    
    if (handle != NULL) {
        xSemaphoreGiveFromISR(handle->tx_semaphore, NULL);
    }
}

void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) {
    can_handle_t *handle = NULL;
    
    if (hcan->Instance == CAN1 && can1_handle != NULL) {
        handle = can1_handle;
    } else if (hcan->Instance == CAN2 && can2_handle != NULL) {
        handle = can2_handle;
    }
    
    if (handle != NULL) {
        xSemaphoreGiveFromISR(handle->tx_semaphore, NULL);
    }
}

void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) {
    can_handle_t *handle = NULL;
    
    if (hcan->Instance == CAN1 && can1_handle != NULL) {
        handle = can1_handle;
    } else if (hcan->Instance == CAN2 && can2_handle != NULL) {
        handle = can2_handle;
    }
    
    if (handle != NULL) {
        xSemaphoreGiveFromISR(handle->tx_semaphore, NULL);
    }
}

// 中断处理函数
void CAN1_TX_IRQHandler(void) {
    HAL_CAN_IRQHandler(&can1_handle->hcan);
}

void CAN1_RX0_IRQHandler(void) {
    HAL_CAN_IRQHandler(&can1_handle->hcan);
}

void CAN1_RX1_IRQHandler(void) {
    HAL_CAN_IRQHandler(&can1_handle->hcan);
}

void CAN1_SCE_IRQHandler(void) {
    HAL_CAN_IRQHandler(&can1_handle->hcan);
}

void CAN2_TX_IRQHandler(void) {
    if (can2_handle != NULL) {
        HAL_CAN_IRQHandler(&can2_handle->hcan);
    }
}

void CAN2_RX0_IRQHandler(void) {
    if (can2_handle != NULL) {
        HAL_CAN_IRQHandler(&can2_handle->hcan);
    }
}

void CAN2_RX1_IRQHandler(void) {
    if (can2_handle != NULL) {
        HAL_CAN_IRQHandler(&can2_handle->hcan);
    }
}

void CAN2_SCE_IRQHandler(void) {
    if (can2_handle != NULL) {
        HAL_CAN_IRQHandler(&can2_handle->hcan);
    }
}
